package com.hyts.network.service.netty;

import java.util.Objects;
import java.util.concurrent.ExecutorService;
import java.util.logging.Logger;


import com.hyts.network.core.Server;
import com.hyts.network.error.ConnectionException;
import com.hyts.network.server.NettyServiceFactoryBean;
import com.hyts.network.task.AbstractExecutor;
import com.hyts.network.task.impl.netty.NettyTaskExecutor;
import com.hyts.network.task.impl.netty.NettyTaskExecutorAdaptor;
import io.netty.channel.Channel;
import io.netty.channel.ChannelFuture;
import io.netty.channel.ChannelInitializer;
import io.netty.channel.ChannelPipeline;
import io.netty.channel.socket.SocketChannel;
import io.netty.channel.socket.nio.NioServerSocketChannel;
import io.netty.handler.codec.serialization.ClassResolvers;
import io.netty.handler.codec.serialization.ObjectDecoder;
import io.netty.handler.codec.serialization.ObjectEncoder;
import io.netty.util.concurrent.Future;
import io.netty.util.concurrent.GenericFutureListener;
/** 
 * @author LiBo/Alex
 * @see com.hyts.network.server.NettyServiceFactoryBean<ExecutorService>
 * @see com.hyts.network.core.Server
 * @version V1.0 
 */  
public class NettyServer extends NettyServiceFactoryBean<ExecutorService> implements Server {
	
	/**
     * field-name: logger
     * field-type: Logger
     * description: 日志输出器
     */
    private Logger logger = Logger.getLogger(this.getClass().getName());

    private Channel channel;
    
	@Override
	public void start(AbstractExecutor<?, ?, ?> executor) {
		if(Objects.isNull(this.getServer()))
			throw new ConnectionException("serverBootstrap对象不允许为空!");
		this.getServer().group(this.getBossEventLoopGroup(), this.getWorkEventLoopGroup())
			.channel(NioServerSocketChannel.class)
			.childHandler(new ChannelInitializer<SocketChannel>() {
				@Override
				protected void initChannel(SocketChannel ch) throws Exception {
					ChannelPipeline pipeline = ch.pipeline();
					pipeline.addLast(new ObjectDecoder(1024 * 1024,
							ClassResolvers.weakCachingConcurrentResolver(this.getClass().getClassLoader())));
					pipeline.addLast(new ObjectEncoder());
					if(executor instanceof NettyTaskExecutor) {
						throw new ConnectionException("executor对象必须为NettyTaskExecutor子类");
					}
					pipeline.addLast(new NettyTaskExecutorAdaptor((NettyTaskExecutor) executor));
				}		
			});
			try {
				channel = this.getServer().bind(getPort()).sync().channel();
			} catch (InterruptedException e) {
				e.printStackTrace();
			}
	}

	@Override
	public void stop() {
		// 监听服务器关闭监听
		try {
			ChannelFuture future = channel.closeFuture().sync();
			future.addListener(new GenericFutureListener() {
				@Override
				public void operationComplete(Future future) throws Exception {
					if(future.isSuccess()) {
						
					}
				}
			});
		} catch (InterruptedException e) {
			e.printStackTrace();
		}finally {
			// 退出
			this.getBossEventLoopGroup().shutdownGracefully();
			this.getWorkEventLoopGroup().shutdownGracefully();
		}
	}

	@Override
	public boolean isClosed() {
		return false;
	}

}
